﻿/*
 * (c) Stefan Bojarovski 2010
 * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASTBuilder
{
    class FunctionCallNode : NodesCollection, IArithmeticNode
    {
        private LexemeType lexType = LexemeType.FUN_CALL;
        private String Name;
        private ITreeNode Argument;

        public FunctionCallNode(String someName, ITreeNode someArgument)
        {
            Name = someName;
            Argument = someArgument;
        }
        public LexemeType getLexemeType()
        {
            return lexType;        
        }
        public void setNegative() { }
        public IArithmeticNode getFirst() { return this; }
        public IArithmeticNode getSecond() { return this; }
        
        public void printNode(String parentlevel, System.IO.StreamWriter someStream)
        {
            someStream.WriteLine(parentlevel + " " + "Function Call: " + Name);
            someStream.WriteLine(parentlevel + " " + "With Argument:");
            Argument.printNode(parentlevel, someStream);
        }
        public List<Command> evalNode(ref Direction next, 
                                        ref Dictionary<string, Pair<IdentifierType, object>> Environment)
        {
            List<Command> funResult = new List<Command>();
            if (next != Direction.JUMP)
            {
                Command result;
                Command arg;
                if (Environment.ContainsKey(Name))
                {
                    if (Environment[Name].getLeft() == IdentifierType.FUNCTION)
                    {
                        //evaluate Argument
                        Command argEval = Argument.evalNode(ref next, ref Environment)[0];
                        //then evaluate Body
                        Pair<IArithmeticNode, IArithmeticNode> funBody = (Pair<IArithmeticNode, IArithmeticNode>)Environment[Name].getRight();
                        arg = funBody.getLeft().evalNode(ref next, ref Environment)[0];
                        result = funBody.getRight().evalNode(ref next, ref Environment)[0];
                    }
                    else
                    {
                        result = new Command(CommandType.ERRORUNCOMPATIBLETYPES, Name, null);
                    }
                }
                else
                {
                    result = new Command(CommandType.ERRORUNDECLAREDID, Name, null);
                }

                funResult.Add(result);
                return funResult;
            }
            else
            {
                funResult.Add(new Command(CommandType.VOID, null, null));
                return funResult;
            }
        }
    }
}
